package com.winit.openapi.sms.common;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.SimpleTimeZone;
import java.util.TimeZone;

import org.apache.commons.lang3.StringUtils;

/**
 * 日期处理常用类
 * 
 * @version <pre>
 * Author	Version		Date		Changes
 * keke.xu 	1.0  		2016年1月13日 	Created
 * 
 * </pre>
 * @since 1.
 */
public class DateUtils {

    private static final String DEF_TIME_ZONE = "GMT+8";        // 时区
    private static final String DATE_FORMAT   = "yyyy-MM-dd";   // 日期格式
    private static final String DATE_FORMAT_1 = "yyyy-MM-dd HH:mm"; // 日期格式

    /**
     * 功能：传入时间按所需格式返回时间字符串
     * 
     * @param date java.util.Date格式
     * @param format yyyy-MM-dd HH:mm:ss | yyyy年MM月dd日 HH时mm分ss秒
     * @return
     */
    public static String format(Date date, String format) {
        String result = null;
        try {
            DateFormat df = new SimpleDateFormat(format);
            df.setTimeZone(TimeZone.getTimeZone(DEF_TIME_ZONE));
            result = df.format(date);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 功能：将时间转成yyyy-MM-dd格式字符串
     * 
     * @param date
     * @return
     */
    public static String format(Date date) {
        return format(date, DATE_FORMAT);
    }

    /**
     * 将日期时间转成yyyy-MM-dd格式的日期
     * 
     * @param date
     * @return
     */
    public static Date parse(Date date) {
        return format(format(date, DATE_FORMAT), DATE_FORMAT);
    }

    /**
     * 功能：传入时间字符串按所需格式返回时间
     * 
     * @param dateStr 时间字符串
     * @param format 跟传入dateStr时间的格式必须一样 yyyy-MM-dd HH:mm:ss | yyyy年MM月dd日
     * HH时mm分ss秒
     * @return
     */
    public static Date format(String dateStr, String format) {

        SimpleDateFormat df = new SimpleDateFormat(format);
        Date date = null;
        df.setTimeZone(TimeZone.getTimeZone(DEF_TIME_ZONE));
        // String time = "2013-06-27 15:46:06";
        try {
            date = df.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
        // parse()方法将给定字符串转成Date
        // format()方法是将Date对象转成对应格式的String
    }

    /**
     * 功能：指定日期加上指定天数
     * 
     * @param date 日期
     * @param day 天数
     * @return 返回相加后的日期
     */
    public static Date addDate(Date date, int day) {
        Calendar c = Calendar.getInstance();
        c.setTimeInMillis(getMillis(date) + ((long) day) * 24 * 3600 * 1000);
        return c.getTime();
    }

    /**
     * 功能：返回毫秒
     * 
     * @param date
     * @return
     */
    public static long getMillis(Date date) {
        if (date == null) {
            date = new Date();
        }
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.getTimeInMillis();
    }

    /**
     * 功能：将时间字符串转成yyyy-MM-dd格式
     * 
     * @param date
     * @return
     */
    public static Date format(String dateStr) {
        return format(dateStr, "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * 功能：时间字符串格式转换,如将2011-01-01转换成20110101
     * 
     * @param dateStr 时间字符串
     * @param format 时间字符串的格式
     * @param toFormat 转换为的格式
     * @return
     */
    public static String format(String dateStr, String format, String toFormat) {
        return format(format(dateStr, format), toFormat);
    }

    /**
     * 功能：格式化rss的时间 输入:
     * 
     * @param date
     * @return
     */
    public static String formatRssDate(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
        SimpleTimeZone zone = new SimpleTimeZone(8, "GMT");
        sdf.setTimeZone(zone);
        return sdf.format(date);
    }

    /**
     * 功能：
     * 
     * @param date 时间
     * @param type 需要获取的单位,如Calendar.YEAR
     * @return
     */
    public static int getElement(Date date, int type) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.get(type);
    }

    /**
     * 功能：返回年
     * 
     * @param date
     * @return
     */
    public static int getYear(Date date) {
        return getElement(date, Calendar.YEAR);

    }

    /**
     * 功能：返回月
     * 
     * @param date
     * @return
     */
    public static int getMonth(Date date) {
        return getElement(date, Calendar.MONTH) + 1;
    }

    /**
     * 功能：返回日
     * 
     * @param date
     * @return
     */
    public static int getDay(Date date) {
        return getElement(date, Calendar.DATE);
    }

    /**
     * 功能：返回小时
     * 
     * @param date
     * @return
     */
    public static int getHour(Date date) {
        return getElement(date, Calendar.HOUR);
    }

    /**
     * 功能：返回分
     * 
     * @param date
     * @return
     */
    public static int getMinute(Date date) {
        return getElement(date, Calendar.MINUTE);
    }

    /**
     * 功能：返回秒
     * 
     * @param date
     * @return
     */
    public static int getSecond(Date date) {
        return getElement(date, Calendar.SECOND);
    }

    /**
     * 功能：返回毫秒
     * 
     * @param date
     * @return
     */
    public static int getMillisecond(Date date) {
        return getElement(date, Calendar.MILLISECOND);
    }

    /**
     * 功能：返回从1970年到指定时间的毫秒数
     * 
     * @param date
     * @return
     */
    public static long getMilliseconds(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.getTimeInMillis();
    }

    /**
     * 功能：返回星期 1：星期一，2:星期二 ... 6:星期六 7:星期日
     * 
     * @param date
     * @return
     */
    public static int getWeek(Date date) {
        int week = getElement(date, Calendar.DAY_OF_WEEK) - 1;
        if (week == 0) {
            return 7;
        } else {
            return week;
        }
    }

    /**
     * 功能：返回星期 1：星期一，2:星期二 ... 6:星期六 7:星期日
     * 
     * @param date
     * @return
     */
    public static String getChinaWeek(Date date) {
        int week = getWeek(date);
        if (week == 1) {
            return "星期一";
        } else if (week == 2) {
            return "星期二";
        } else if (week == 3) {
            return "星期三";
        } else if (week == 4) {
            return "星期四";
        } else if (week == 5) {
            return "星期五";
        } else if (week == 6) {
            return "星期六";
        } else {
            return "星期日";
        }
    }

    /**
     * 功能：获取当前日期 格式:2010-10-10
     * 
     * @return
     */
    public static String getCurrentDate() {
        return format(new Date(), DATE_FORMAT);
    }

    /**
     * 功能：获取当前日期 格式:2008-02-02 23:11:10
     * 
     * @return
     */
    public static String getCurrentDateTime() {
        return format(new Date(), "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * 功能：获取当前月的第一天日期
     * 
     * @return
     */
    public static Date getMonFirstDay() {
        Date date = new Date();
        Calendar c = Calendar.getInstance();
        c.set(getYear(date), getMonth(date) - 1, 1);
        return c.getTime();
    }

    /**
     * 功能：获取当前月的最后一天日期
     * 
     * @return
     */
    public static Date getMonLastDay() {
        Date date = new Date();
        Calendar c = Calendar.getInstance();
        c.set(getYear(date), getMonth(date), 1);
        c.setTimeInMillis(c.getTimeInMillis() - (24 * 60 * 60 * 1000));
        return c.getTime();
    }

    /**
     * 功能：判断一个日期 是否在 两个日期之间
     * 
     * @param date 时间
     * @param startDate 开始日期
     * @param currentDate 当前时间
     * @param endDate 结束日期
     * @return 返回是否在之间
     */
    public static boolean isBetweenDate(Date startDate, Date currentDate, Date endDate) {
        long endMillis = endDate.getTime();
        long startMillis = startDate.getTime();
        long currentMillis = currentDate.getTime();
        if (startMillis <= currentMillis && currentMillis <= endMillis) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 功能:两个日期相隔天数
     * 
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 返回相减后的日期
     */
    public static int diffDate(Date startDate, Date endDate) {
        long endMillis = endDate.getTime();
        long startMillis = startDate.getTime();
        long s = (endMillis - startMillis) / (24 * 60 * 60 * 1000);
        return (int) s;
    }

    /**
     * 功能:两个日期相隔天数
     * 
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 返回相减后的日期
     */
    public static int diffSecond(Date startDate, Date endDate) {
        long endMillis = endDate.getTime();
        long startMillis = startDate.getTime();
        long s = (endMillis - startMillis) / (1000);
        return (int) s;
    }

    public static int diff(Date date1, Date date2) {
        Calendar c1 = Calendar.getInstance();
        c1.setTime(date1);
        Calendar c2 = Calendar.getInstance();
        c2.setTime(date2);
        return c1.compareTo(c2);
    }

    /**
     * 功能：两个日期字符串相隔天数
     * 
     * @param startDateStr 开始时间字符串
     * @param endDateStr 结束时间字符串
     * @return
     */
    public static int diffDate(String startDateStr, String endDateStr) {
        return diffDate(format(startDateStr), format(endDateStr));
    }

    /**
     * 功能：计算时间相差
     * 
     * @param date 时间
     * @param type 需要计算的相差单位,如Calendar.YEAR
     * @param num 相差数,正数为在date上增加,负数为相减
     * @return
     */
    public static Date diff(Date date, int type, int num) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(type, num);
        return c.getTime();
    }

    /**
     * 功能：指定日期加上/减去指定年
     * 
     * @param date 日期
     * @param year 年数,正数相加,负数相减
     * @return
     */
    public static Date diffYear(Date date, int year) {
        return diff(date, Calendar.YEAR, year);
    }

    /**
     * 功能：指定日期加上/减去指定月
     * 
     * @param date 日期
     * @param month 月数,正数相加,负数相减
     * @return
     */
    public static Date diffMonth(Date date, int month) {
        return diff(date, Calendar.MONTH, month);
    }

    /**
     * 功能：指定日期加上/减去指定天数
     * 
     * @param date 日期
     * @param day 天数,正数相加,负数相减
     * @return
     */
    public static Date diffDate(Date date, int day) {
        return diff(date, Calendar.DATE, day);

    }

    /**
     * 功能：指定日期加上/减去指定分钟数
     * 
     * @param date 日期
     * @param minute 分钟数,正数相加,负数相减
     * @return
     */
    public static Date diffMinute(Date date, int minute) {
        return diff(date, Calendar.MINUTE, minute);
    }

    /**
     * 功能：判断字符串是否是符合格式的时间字符串;如果format为空,则只判断是否是时间字符串
     * 
     * @param dateStr
     * @param format
     * @return
     */
    public static boolean isDateStr(String dateStr, String format) {
        boolean checkFormat = true;// 是否需要判断时间格式
        if (StringUtils.isBlank(format)) {
            format = DATE_FORMAT;
            checkFormat = false;
        }
        DateFormat df = new SimpleDateFormat(format);
        Date d = null;
        try {
            d = df.parse(dateStr);
        } catch (Exception e) {
            return false;// 如果不能转换,肯定是错误格式
        }
        if (checkFormat) {
            return dateStr.equals(df.format(d));// 转换后的日期再转换回String,如果不等,逻辑错误
        } else {// 不检查格式
            return true;
        }
    }

    /**
     * 功能：判断是否是时间对象或时间字符串
     * 
     * @param obj
     * @return
     */
    public static boolean isDate(Object obj) {
        if (obj == null) {
            return false;
        } else if (obj instanceof java.util.Date) {
            return true;
        } else if (obj instanceof java.sql.Date) {
            return true;
        } else if (obj instanceof String) {
            return isDateStr(obj.toString(), null);
        }
        return false;
    }

    /**
     * 格式化日期保留小时
     * @param date
     * @return
     */
    public static String formatHHmm(Date date) {
        return format(date, DATE_FORMAT_1);
    }

    public static void main(String[] args) {
        System.out.println(diffSecond(DateUtils.format("2013-08-10 13:00:00", "yyyy-MM-dd HH:mm:ss"),
            DateUtils.format("2013-08-10 13:02:00", "yyyy-MM-dd HH:mm:ss")));
    }
}
